/**
 * Ingenius-Group S.A.S
 *
 * Project: SAU
 * File: EditGroupPresenter.java
 * Date: 02/03/2011
 */

package com.ingenius.sau.client.presenter;

import java.util.ArrayList;
import java.util.List;

import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.ingenius.sau.client.AppController;
import com.ingenius.sau.client.Constants;
import com.ingenius.sau.client.event.ListGroupsEvent;
import com.ingenius.sau.client.model.UserBaseModel;
import com.ingenius.sau.client.service.UsersServiceAsync;
import com.ingenius.sau.client.view.Display;
import com.ingenius.sau.shared.model.users.Group;
import com.ingenius.sau.shared.model.users.User;

/**
 * Class <strong>EditGroupPresenter</strong>
 * 
 * @author Jesus David
 * @version 0.1
 */
public class EditGroupPresenter implements EditPresenter {

	public interface EditGroupDisplay extends Display {

		String getName();

		void setName(String name);

		String getDescription();

		void setDescription(String description);

		void addStoreFrom(List<UserBaseModel> users);

		void addStoreTo(List<UserBaseModel> users);

		List<String> getUserIds();

		void show();

		void hide();
	}

	private final HandlerManager eventBus;
	private final UsersServiceAsync rpcService;
	private final EditGroupDisplay display;
	private Group group;

	public EditGroupPresenter(HandlerManager eventBus,
			UsersServiceAsync rpcService, EditGroupDisplay display,
			String groupId) {

		this.rpcService = rpcService;
		this.eventBus = eventBus;
		this.display = display;
		display.setPresenter(this);
		if (groupId == null) {
			group = new Group();
		} else {
			loadBean(groupId);
		}
		loadStores();
	}

	private void loadStores() {
		rpcService.findUsers(null, null,
				new AsyncCallback<PagingLoadResult<User>>() {
					@Override
					public void onSuccess(PagingLoadResult<User> result) {
						List<UserBaseModel> listFrom = new ArrayList<UserBaseModel>();
						List<UserBaseModel> listTo = new ArrayList<UserBaseModel>();
						for (User user : result.getData()) {
							UserBaseModel userBM = new UserBaseModel();
							userBM.setId(user.getId());
							userBM.setUsername(user.getUsername() + " ("
									+ user.getRole().getName() + ")");

							if (group != null
									&& group.getUsersIds().contains(
											user.getId())) {
								listTo.add(userBM);
							} else {
								listFrom.add(userBM);
							}
						}
						display.addStoreFrom(listFrom);
						display.addStoreTo(listTo);
					}

					@Override
					public void onFailure(Throwable caught) {

					}
				});
	}

	private void loadBean(String groupId) {
		AppController.setStatusMessage("Loading...");
		rpcService.getGroup(groupId, new AsyncCallback<Group>() {
			@Override
			public void onSuccess(Group result) {
				if (result == null) {
					onFailure(new Throwable("Database error"));
					return;
				}
				group = result;
				display.setName(group.getName());
				display.setDescription(group.getDescription());
				hideStatusMessage();
			}

			@Override
			public void onFailure(Throwable caught) {
				GWT.log(Constants.MESSAGE_FAILED_GET + Group.class.getName(),
						caught);
				group = new Group();
				// TODO i18n
				String failedMessage = "Failed to retrieve group";
				display.showInfo(failedMessage);
				hideStatusMessage();
			}

			void hideStatusMessage() {
				AppController.hideStatusMessage();
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ingenius.sau.client.presenter.EditPresenter#doSaveOrUpdate()
	 */
	@Override
	public void doSaveOrUpdate() {
		group.setName(display.getName());
		group.setDescription(display.getDescription());
		group.setUsersIds(display.getUserIds());

		// TODO i18n
		final String failedMessage = "Failed to save group";
		final String successMessage = "Group saved sucessfully";

		display.hide();
		AppController.setStatusMessage("Saving...");
		rpcService.saveOrUpdateGroup(group, new AsyncCallback<Boolean>() {
			@Override
			public void onSuccess(Boolean result) {
				if (result) {
					eventBus.fireEvent(new ListGroupsEvent());
					display.showInfo(successMessage);
					hideStatusMessage();

				} else {
					onFailure(new Throwable("Database error"));
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				GWT.log(Constants.MESSAGE_FAILED_SAVE + Group.class.getName(),
						caught);
				display.showInfo(failedMessage);
				hideStatusMessage();
			}

			void hideStatusMessage() {
				AppController.hideStatusMessage();
			}
		});
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.ingenius.sau.client.presenter.Presenter#go(com.google.gwt.user.client
	 * .ui.HasWidgets)
	 */
	@Override
	public void go(HasWidgets container) {
		display.show();
	}

	public List<UserBaseModel> loadUsers() {
		rpcService.findUsers(null, null,
				new AsyncCallback<PagingLoadResult<User>>() {

					@Override
					public void onSuccess(PagingLoadResult<User> result) {
						// TODO Auto-generated method stub

					}

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub

					}
				});

		return new ArrayList<UserBaseModel>();
	}

}
